﻿using ManagementApi.Mvc;
using ManagementApi.Mvc.ApplicationContexts;
using Modules;
using Modules.Constructor;
using Modules.Corp;
using Modules.Project;
using Modules.System.User;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Entity;

namespace ManagementApi.Authorizers
{
    /// <summary>
    /// 项目数据权限验证
    /// </summary>
    [UseDI(ServiceLifetime.Scoped)]
    public class ProjectOwnAuthorizer
    {
        private readonly ProjectService projectService;
        private readonly ProjectUserApplicationContext applicationContext;

        /// <summary>
        /// 项目数据权限验证
        /// </summary>
        /// <param name="applicationContext"></param>
        /// <param name="projectService"></param>
        public ProjectOwnAuthorizer(ProjectUserApplicationContext applicationContext,
            ProjectService projectService)
        {
            this.projectService = projectService;
            this.applicationContext = applicationContext;
        }

        /// <summary>
        /// 检查并抛出数据权限验证失败信息
        /// </summary>
        /// <param name="projectId"></param>
        /// <exception cref="OwnAuthorizationFailedException"></exception>
        public void CheckAndThrowIfOwnAuthenticationFailed(int projectId)
        {
            var projectInfo = projectService.GetProjectInfo(projectId) ?? throw new OwnAuthorizationFailedException();
            var user = applicationContext.CurrentUser;

            if (user is DeptUser deptUser)
            {
                if (deptUser.IndustryType != projectInfo.IndustryType)
                    throw new OwnAuthorizationFailedException();
            }
            if (user is IProjectUser)
            {
                if (projectId != applicationContext.CurrentProjectInfo.ProjectId)
                {
                    throw new OwnAuthorizationFailedException();
                }
            }
        }

        /// <summary>
        /// 检查并抛出数据权限验证失败信息
        /// </summary>
        /// <param name="projectIds"></param>
        public void CheckAndThrowIfOwnAuthenticationFailed(IEnumerable<int> projectIds)
        {
            foreach (int projectId in projectIds)
                CheckAndThrowIfOwnAuthenticationFailed(projectId);
        }
    }
}